﻿using System;
using Macad.Common;
using Macad.Core;
using Macad.Core.Shapes;
using Macad.Core.Topology;
using Macad.Interaction;
using Macad.Occt;
using SpCad.Tools;
using SpCad.Utils;
using SPCAM.Plugin.Cam.Enums;
using SPCAM.Plugin.Cam.Model;
using SPCAM.Plugin.Cam.Servers;
using static Macad.Interaction.ToggleSubshapesAction;

namespace SPCAM.Plugin.Cam.Tools
{
    public enum FaceToEdgeType
    {
        相交, 合并
    }
    public class SelectFasceTools : Tool
    {
        #region 属性
        readonly Body _TargetBody;
        /// <summary>
        /// 边缘形状即GetBRep()
        /// </summary>
        protected TopoDS_Shape EdgeBRep;
        /// <summary>
        /// 轮廓边缘
        /// </summary>
        protected TopoDS_Edge[] ContourEdges;
        /// <summary>
        /// 有效边
        /// </summary>
        protected TopoDS_Edge[] ValidEdges;
        /// <summary>
        /// 选择面完成开始选择边框
        /// </summary>
        protected bool SelectFaceOver = false;
        /// <summary>
        /// 选择边的类型相交\相切\周边
        /// </summary>
        protected SelectFcaeTypeEnum _FaceToEdgeTypeEnum;

        /// <summary>
        /// 已选择的面
        /// </summary>
        public List<Subshape> _SelectFaces = new List<Subshape>();


        List<TopoDS_Edge> SelectEdges { get; set; } = new List<TopoDS_Edge>();

        public Color SelectColor { get; set; } = AIS_Shape_Color.SelctYell;
        public bool IsNoCanExit { get; set; } = false;


        SelectAction toolAction;

        #endregion



        //-----------------------------------------------------------------------------------





        public SelectFasceTools(Body targetBody)
        {

            _TargetBody = targetBody;
        }
        protected override bool OnStart()
        {
            // 初始化 ToolAction，从 Face 类型中选择子形状

            Shape.ShapeChanged += _EdgeModifierBase_ShapeChanged;
            UpdateActions();
            SetHintMessage("选择面");
            SetCursor(Cursors.SelectFace);
            return true;
        }

        protected virtual bool UpdateActions()
        {
            IsNoCanExit = true;
            _StopAction();
            foreach (var item in WeldServer.Get.SelectEdges)
            {
                item.Location(new TopLoc_Location(_TargetBody.GetTransformation()));


            }
            //  toolAction.UpdateShapes(_SelectFaces, _TargetBody.GetTransformation());
            foreach (var item in _SelectFaces)
            {
                ClearShape(item.AisShape);
                item.Shape.Location(new TopLoc_Location(_TargetBody.GetTransformation()));
                var axshap = new AIS_Shape(item.Shape);
                item.AisShape = axshap;
                SetAis_Shape_Face(axshap); //给face添加颜色
            }
            if (!SelectFaceOver)
            {
                var Plane = new FaceSelectionFilter(FaceSelectionFilter.FaceType.Plane);
                var Cone = new FaceSelectionFilter(FaceSelectionFilter.FaceType.Cone);
                var Cylinder = new FaceSelectionFilter(FaceSelectionFilter.FaceType.Cylinder);
                toolAction = new SelectAction(SubshapeTypes.All, _TargetBody, new OrSelectionFilter(Plane, Cone, Cylinder));
                if (!StartAction(toolAction, false))
                {
                    return false;
                }
                toolAction.Finished += ToolAction_Finished;



            }
            else
            {
                if (_SelectFaces.Count > 0)
                {
                    ActionEdge();
                }

            }

            IsNoCanExit = false;
            return true;
        }
        void _StopAction()
        {
            if (toolAction != null)
            {
                toolAction.Finished -= ToolAction_Finished;
            }
            StopAction(toolAction);
        }
        /// <summary>
        /// 鼠标选择
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        private void ToolAction_Finished(SelectAction sender, SelectAction.EventArgs args)
        {
            if (args.SelectedSubshapeType == SubshapeTypes.Face)
            {
                var face = args.SelectedSubshape.ToFace();

                AddSelectShape(face); //添加到List 
            }
            else
            {
                SetHintMessage("选中的面不是平面、圆柱面或圆锥面.");
            }
        }
        /// <summary>
        /// 添加选择对象
        /// </summary>
        /// <param name="edg"></param>
        public void AddSelectShape(TopoDS_Face dS_Face)
        {
            if (dS_Face == null) return;
            var _findface = _SelectFaces.Find(c => c.Shape.IsSame(dS_Face));
            if (_findface != null)
            { //已经存在,删除
                ClearShape(_findface.AisShape);
                _SelectFaces.Remove(_findface);
            }
            else
            {
                dS_Face.Location(new TopLoc_Location(_TargetBody.GetTransformation()));
                AIS_Shape _AisShape = new AIS_Shape(dS_Face);
                SetAis_Shape_Face(_AisShape); //给face添加颜色
                                              //   SetAis_Shape_Face(_AisShape, _TargetBody.GetTransformation()); //给face添加颜色
                _SelectFaces.Add(new Subshape { Shape = dS_Face, AisShape = _AisShape });
            }
        }

        #region 自动提取焊缝
        /// <summary>
        /// 提取面的边框并激活选择
        /// </summary>
        /// <param name="selectface"></param>
        /// <returns></returns>
        public List<TopoDS_Edge> FaceActionEdge(SelectFcaeTypeEnum selectface = SelectFcaeTypeEnum.周边)
        {
            _FaceToEdgeTypeEnum = selectface;
            SelectFaceOver = true;
            //_StopAction();
            List<TopoDS_Edge> selectEdgesList = new List<TopoDS_Edge>();
            if (selectface == SelectFcaeTypeEnum.相交)
            {
                List<TopoDS_Edge> allEdgeList = new List<TopoDS_Edge>();
                if (_SelectFaces == null || _SelectFaces.Count < 2)
                {
                    SetHintMessage("至少需要两个面来查找共有边.");
                    return selectEdgesList;
                }
                foreach (var item in _SelectFaces)
                {
                    //  _TargetBody.Shape.FindSubshape(item.Shape, null);
                    allEdgeList.AddRange(item.Shape.Edges());
                }
                for (int i = 0; i < allEdgeList.Count; i++)
                {
                    var item = allEdgeList[i];
                    allEdgeList.RemoveAt(i);
                    //if (allEdgeList.Any(e => AreEdgesSame(item, e)))
                    //{
                    //    selectEdgesList.Add(item);
                    //}
                    if (allEdgeList.Any(e => item.IsPartner(e)))
                    {
                        selectEdgesList.Add(item);
                    }
                    i--; // 调整索引，因为删除元素后集合大小减少
                }
            }
            else if (selectface == SelectFcaeTypeEnum.相切)
            {
                if (_SelectFaces == null || _SelectFaces.Count < 2)
                {
                    SetHintMessage("至少需要两个面来查找共有边.");
                    return selectEdgesList;
                }
                foreach (var item in _SelectFaces)
                {
                    selectEdgesList.AddRange(item.Shape.Edges());
                }
            }
            else if (selectface == SelectFcaeTypeEnum.周边)
            {
                List<TopoDS_Edge> allEdgeList = new List<TopoDS_Edge>();
                foreach (var item in _SelectFaces)
                {

                    allEdgeList.AddRange(item.Shape.Edges());

                    //  allEdgeList.AddRange(edges);


                }


                foreach (var item in allEdgeList)
                {
                    var edg = selectEdgesList.Find(edge => edge.IsPartner(item));
                    if (edg == null)
                    {
                        selectEdgesList.Add(item);

                    }


                }
            }
            WeldServer.Get.SelectEdges.Clear();
            selectEdgesList.ForEach(edge =>
            {
                var aixshap = new AIS_Shape(edge);
                //  SetAis_Shape_Face(new AIS_Shape(edge));
                //   aixshap.SetColor(Color.White.ToQuantityColor());
                //  SetAis_Shape_Face(aixshap, _TargetBody.GetTransformation());
                WeldServer.Get.SelectEdges.Add(edge);

            });
            SelectEdges = selectEdgesList;

            ActionEdge();
            return SelectEdges;
        }


        public void ActionEdge()
        {
            IsNoCanExit = true;
            _StopAction();
            toolAction = new SelectAction(SubshapeTypes.Edge, SelectEdges, _TargetBody);
            if (!StartAction(toolAction, false))
            {
                Stop();
                return;
            }
            var trsftran = _TargetBody?.GetTransformation();
            //  SelectEdges.ForEach(c => toolAction.AddSubshape(c, trsftran.Value, true));
            toolAction.Preview += NewAction_Preview; ;
            toolAction.Finished += NewAction_Finished; ;

            SetHintMessage("请选择__边框__.");
            SetCursor(Cursors.SelectEdge);

            WorkspaceController.Invalidate();
            IsNoCanExit = false;
        }
        #endregion 

        private void NewAction_Finished(SelectAction sender, SelectAction.EventArgs args)
        {
            if (!args.IsDo) { return; }



            TopoDS_Shape topshape = args.SelectedSubshape;
            TopoDS_Edge seld = (TopoDS_Edge)topshape;
            var subshape = WeldServer.Get.SelectEdges.FirstOrDefault(sh => sh.IsPartner(seld));
            if (subshape == null)
            {

                //   WeldServer.Get.TreeNode.Add(new WeldTreeModel(subshape,_TargetBody.GetTransformation())); 
                seld.Move(new TopLoc_Location(_TargetBody.GetTransformation()));
                //seld.Moved
                WeldServer.Get.SelectEdges.Add(seld);
                SelectEdges.Add(seld);
            }
            else
            {
                WeldServer.Get.SelectEdges.Remove(subshape);
                SelectEdges.Remove(subshape);
            }
        }

        private void NewAction_Preview(SelectAction sender, SelectAction.EventArgs args)
        {
            var _sender = sender;
        }

        #region 选择着色器
        /// <summary>
        /// 设置Face颜色
        /// </summary>
        /// <param name="edg"></param>
        /// <returns></returns>
        private AIS_Shape SetAis_Shape_Face(AIS_Shape _AisShape, Trsf? trsf = null)
        {
            _AisShape.SetZLayer(-2); // Graphic3d_ZLayerId_Top
            _AisShape.SetColor(SelectColor.ToQuantityColor());
            if (trsf != null)
            {
                _AisShape.SetLocalTransformation(trsf.Value);

            }
            _AisShape.Attributes().FaceBoundaryAspect().SetWidth(10);
            _AisShape.Attributes().WireAspect().SetWidth(50);
            //  _AisShape.Attributes().WireAspect().SetColor(Colors.FilteredSubshapesHot);
            InteractiveContext.Current.WorkspaceController.Workspace.AisContext.Display(_AisShape, false);
            InteractiveContext.Current.WorkspaceController.Workspace.AisContext.Deactivate(_AisShape);

            return _AisShape;
        }
        /// <summary>
        /// 清除选择对象
        /// </summary>
        public void ClearShape(AIS_Shape _AisShape)
        {
            if (_AisShape != null)
            {
                InteractiveContext.Current.WorkspaceController.Workspace.AisContext.Remove(_AisShape, false);
                InteractiveContext.Current.WorkspaceController.Workspace.AisContext.Erase(_AisShape, false);
                _AisShape = null;
            }
        }
        #endregion

        protected override void OnStop()
        {
            Shape.ShapeChanged -= _EdgeModifierBase_ShapeChanged;
            _SelectFaces.ForEach(p => { ClearShape(p.AisShape); });
            _SelectFaces.Clear();

            base.OnStop();
        }
        void _EdgeModifierBase_ShapeChanged(Shape shape)
        {
            if (shape == _TargetBody.Shape && toolAction != null && WorkspaceController.CurrentTool?.CurrentAction == toolAction)
            {
                UpdateActions();

            }
        }
    }
}
